Carbon

     

Passing Input and Output Parameters to a New Thread

When you create a new thread, you can pass data to it by passing a parameter to the thread entry function. You can also retrieve data from the thread when it terminates. You set up the storage for this data when you create the thread.

Listing 9 shows how to pass data to a newly created thread and create the storage to hold the data returned by the new thread when it terminates.

Listing 9  Passing data between threads

#define kNoCreationOptions                  0   /* Use the standard default 
                                                    creation options     */
#define kDefaultThreadStackSize             0   /* Use the default value*/ 

/* Define a structure */
struct ExampleRecord {
    long        someLongValue;
    short       someShortValue;
    };
typedef struct ExampleRecord ExampleRecord;
typedef ExampleRecord *ExampleRecordPtr;

void MyParametersExample (void)
{
    ThreadID                    tempThreadID;
    OSErr                       err;
    long                        myLong;
    short                       myShort;
    Boolean                     notDone = true;
    ExampleRecordPtr            recordOutResult = nil;      /* Declare a variable to
                                                                 store new thread's output */
    ExampleRecord               recordInParam;              /* Declare a variable to pass
                                                                data to a new thread */

/* Assign values to pass to a new thread */
    recordInParam.someLongValue = 0x1FFF2EEE;
    recordInParam.someShortValue = 0xABCD;

/* Create a new thread */
    err = NewThread(kCooperativeThread, 
                        (ThreadEntryProcPtr)(MyExampleFunc),
                        (void*)&recordInParam, 
                        kDefaultThreadStackSize, 
                        kNoCreationOptionss,
                        (void**)&recordOutResult, 
                        &tempThreadID);
    if (err)
        DebugStr("\p Could not make coop thread 2");

    while (notDone)
        {
        YieldToAnyThread();/* Other threads run. */

        if (recordOutResult != nil)
            {
            myLong = recordOutResult->someLongValue;                /* Store thread output */
            myShort = recordOutResult->someShortValue;              /* Store thread output */
            DoStuffWithParams(myLong, myShort);                     /* Use thread output */
            DisposePtr((Ptr)recordOutResult);                       /* Remove storage */
            recordOutResult = nil;                                  /* Neutralize variable */
            }
/* Handle user events until quit time */
        GoHandleEvents(&notDone);
        }
    return;                                                         /* Done. */

/* Thread entry function */
pascal ExampleRecordPtr MyExampleFunc (ExampleRecordPtr inputRecordParam)
{
    ExampleRecordPtr        myRecordPtr;
    
    myRecordPtr = NewPtr(sizeof(ExampleRecord));
    myRecordPtr->someLongValue = inputRecordParam->someLongValue;
    myRecordPtr->someShortValue = inputRecordParam->someShortValue;

/* Do some calculations on the data and put the result in myRecordPtr */
                ...
    return (myRecordPtr);/* Must be the size of a void*. */
}

The first thing the code in Listing 9 does is to define some symbolic variables to make the code easier to read. When you create a thread with the NewThread function, you can specify some options that define the behavior of the thread, and you must specify a stack size for the thread. The two #define statements define variables that specify to use the default options and to use the default stack size.

The ExampleRecord structure defines a type of structure that later is used to pass a long and a short value to a new thread and then back again. The code creates the ExampleRecord type and also a pointer to it.

The MyParametersExample function performs the major work in this example. It first declares some variables, including recordInParam and recordOutResult . Note that recordInParam , which is used to pass data to a newly created thread, is declared as an ExampleRecord structure, and recordOutResult , which is used to store data returned from the new thread, is declared as a pointer to an ExampleRecord structure.

Next, MyParametersExample assigns hex values to the someShortValue and someLongValue fields of the recordInParam structure. It then uses the NewThread function to create a new thread. It specifies MyExampleFunc as the thread's entry function and passes it the recordInParam structure. It also specifies recordOutResult as the storage for any data returned from the new thread. Note that NewThread passes recordInParam as a pointer to a value and recordOutResult as a pointer to an address. As you recall, recordInParam is defined as an ExampleRecord structure and recordOutResult as a pointer to an ExampleRecord structure.

The MyParametersExample function then sets up a while loop to see if the newly created thread has returned any data yet. The YieldToAnyThread function guarantees that the newly created thread--and any other thread in the application--gets time to run. The variables myLong and myShort hold the data that the new thread returns. The DoStuffWithParams function, whose code is not shown here, passes in these variables and does some additional work on the data. The Memory Manager DisposePtr function frees the memory used by the recordOutResult structure. Note that the while loop also contains a function to handle user events.

The MyExampleFunc function is the entry point to the thread that the MyParametersExample function created with the NewThread function. It declares myRecordPtr as an ExampleRecordPtr and then uses the Memory Manager NewPtr function to allocate a block of memory for it that is the size of an ExampleRecord structure. It then passes the hex values from the NewThread function to the someLongValue and someshortValue fields of the structure pointed to by myRecordPtr .

After doing some calculations on the hex values, MyExampleFunc returns the data to the storage allocated in the MyParametersExample function.


© 2000 Apple Computer, Inc. – (Last Updated 09 May 00)